package RecyclingAbteilung;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import test.Zauberkasten;
import firma.AbstractAbteilung;
import firma.Auftrag;
import firma.Container;
import firma.TestAbteilung;
import firma.TestFirma;
import firma.ZeitPunkt;
import firma.ZeitSpanne;
import firma.AbstractAbteilung.AbteilungsTyp;

/**
 * Beispiel fuer Studenten fuer eine Testklasse.
 * 
 * @author Nicole
 */

// TODO Student fuer jede Testfolge:
// dieses Template Kopieren, Umbenennen und Anpassen

public class Testfolge1 {

	/**
	 * Fuehrt eine Testfolge auf einer Abteilung aus
	 * 
	 * @param args
	 *            nicht ausgewertet
	 */
	public static void main(String[] args) // throws Throwable
	{
		String curDir = System.getProperty("user.dir");
		String dirSep = System.getProperty("file.separator");
		TestFirma firma;
		try {
			firma = new TestFirma(curDir + dirSep + "musterkatalog.xml");
		} catch (Exception e) {
			System.err.println(e.getMessage());
			System.err
					.println("Fehler beim Erstellen des Musterkatalogs. Wurde der richtige Dateiname angegeben?");
			e.printStackTrace();
			return;
		}

		// *********************
		// zu testende Abteilung
		// *********************

		AbstractAbteilung r_abt = new Recycling();

		// *********************

		firma.setZuTestendeAbteilung(r_abt);

		SortedMap<ZeitPunkt, Auftrag> auftraege = new TreeMap<ZeitPunkt, Auftrag>();
		// fuellen - Achtung! den gleichen Zeitpunkt nicht zwei mal
						
		SortedMap<ZeitPunkt, Container> container = new TreeMap<ZeitPunkt, Container>();
		// fuellen - Achtung! den gleichen Zeitpunkt nicht zwei mal

		// ********************
		// Beginn der Testfolge
		// ********************

		// Testabteilung, die bei uns bestellt
		// TODO Student Abteilungstyp aendern?
		TestAbteilung ta1 = new TestAbteilung(AbteilungsTyp.QUALITAETSSICHERUNG);

		// TODO Student Auftraege der Testfolge einfuegen
		// auftraege.put(..., ...);
		Auftrag auftrag1 = new Auftrag("001r", r_abt, ta1, new ZeitPunkt(2L), dirSep, 1);
		auftraege.put(new ZeitPunkt(6L),auftrag1 );
		
		//Beispielhaft

		// Testabteilung, die die (von uns beauftragten) Teile liefert
		// TODO Student Abteilungstyp aendern?
		TestAbteilung ta2 = new TestAbteilung(AbteilungsTyp.QUALITAETSSICHERUNG);
		// Zauberkasten zum fuellen der Test-Container
		Zauberkasten zk = new Zauberkasten();

		// TODO Student Container der Testfolge einfuegen
		container.put(new ZeitPunkt(3L), new Container(auftrag1, "C01"));

		// ******************
		// Ende der Testfolge
		// ******************

		System.out.println("\n**** Start Funktionstest *****\n");

		// Ausfuehrung: Auftraege & Container in der richtigen Reihenfolge
		// reinwerfen
		Iterator<ZeitPunkt> auftragsZeitPunkte = auftraege.keySet().iterator();
		Iterator<ZeitPunkt> containerZeitPunkte = container.keySet().iterator();

		boolean auftNext = auftragsZeitPunkte.hasNext();
		ZeitPunkt auftZP = auftNext ? auftragsZeitPunkte.next() : null;
		boolean contNext = containerZeitPunkte.hasNext();
		ZeitPunkt contZP = contNext ? containerZeitPunkte.next() : null;

		ZeitPunkt simZP = new ZeitPunkt(0L);
		ZeitSpanne simZS = new ZeitSpanne(300L);

		while (true
		// abbruchbedingung im ersten if(...) (im ersten try{...}
		) {
			// teil der abbruchbedingung benoetigt try catch
			// um ein riesiges try zu vermeiden, ist die bedingung in die
			// Schleifen reingezogen

			// schleifen-abbruchbedinung
			if (!((auftNext || contNext) || r_abt.getAnzahlAuftraege() > 0))
				break;

			if (auftNext && (!contNext || (contNext && auftZP.istVor(contZP)))) {
				// arbeiten, wenn vorher dran!
				if (simZP.istVor(auftZP)) {
					// Zeit konsistent halten!
					firma.setSimulationsZeitPunkt(simZP);

					System.out.println("\n** " + simZP.toString()
							+ " - getestete Abteilung beginnt zu arbeiten ...");

					// arbeiten
					r_abt.arbeite(simZP, simZS);

					System.out
							.println("** getestete Abteilung ist fertig mit arbeiten.\n");

					// Zeit weiterdrehen
					simZP = simZP.nachZeitSpanne(simZS);
					continue;
				}

				Auftrag aft = auftraege.get(auftZP);

				// auftrag an die Abteilung geben
				System.out
						.println("\n** sende Auftrag an zu testende Abteilung ... **");
				System.out.println(aft);
				System.out.println("**\n");
				r_abt.erhalteAuftrag(aft);
				System.out.println("** Auftrag gesendet. **\n");

				auftNext = auftragsZeitPunkte.hasNext();
				auftZP = auftNext ? auftragsZeitPunkte.next() : null;
				continue;
			}
			// else

			if (contNext) {
				// arbeiten, wenn vorher dran!
				if (simZP.istVor(contZP)) {
					// Zeit konsistent halten!
					firma.setSimulationsZeitPunkt(simZP);

					System.out.println("\n** " + simZP.toString()
							+ " - getestete Abteilung beginnt zu arbeiten ...");

					// arbeiten
					r_abt.arbeite(simZP, simZS);

					System.out
							.println("** getestete Abteilung ist fertig mit arbeiten.\n");

					// Zeit weiterdrehen
					simZP = simZP.nachZeitSpanne(simZS);
					continue;
				}

				Container cnt = container.get(contZP);

				// Container an Abteilung geben
				System.out
						.println("\n** sende Container an zu testende Abteilung ... **");
				System.out.println(cnt);
				System.out.println("**\n");

				r_abt.erhalteTeile(cnt);

				System.out.println("** Container gesendet. **\n");

				contNext = containerZeitPunkte.hasNext();
				contZP = contNext ? containerZeitPunkte.next() : null;
				continue;
			}
			// else

			// nur noch arbeiten!
			// Zeit konsistent halten!
			firma.setSimulationsZeitPunkt(simZP);

			System.out.println("\n** " + simZP.toString()
					+ " - getestete Abteilung beginnt zu arbeiten ...");

			// arbeiten
			r_abt.arbeite(simZP, simZS);

			System.out
					.println("** getestete Abteilung ist fertig mit arbeiten.\n");

			// Zeit weiterdrehen
			simZP = simZP.nachZeitSpanne(simZS);

			// Simulation zu ende, endpruefung
			if (r_abt.getAnzahlAuftraege() <= 0)
				break;

		} // end while

		System.out.println("\n**** Ende Funktionstest *****\n");

	}

}



